home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file is part of the portable Forth environment written in ANSI C.
- * Copyright (C) 1995 Dirk Uwe Zoller
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This file is version 0.9.13 of 17-July-95
- * Check for the latest version of this package via anonymous ftp at
- * roxi.rz.fht-mannheim.de:/pub/languages/forth/pfe-VERSION.tar.gz
- * or sunsite.unc.edu:/pub/languages/forth/pfe-VERSION.tar.gz
- * or ftp.cygnus.com:/pub/forth/pfe-VERSION.tar.gz
- *
- * Please direct any comments via internet to
- * duz@roxi.rz.fht-mannheim.de.
- * Thank You.
- */
- /*
- * locals.c --- The Optional Locals Word Set
- * (duz 08Jul93)
- */
-
- #include <string.h>
-
- #include "forth.h"
- #include "support.h"
- #include "compiler.h"
-
- /* 1. Actions at runtime: */
-
- code (locals_bar_execution) /* establish local variables on return stack */
- {
- Cell *p, *q;
- Cell n;
-
- p = sp;
- q = RP;
- for (n = (Cell) *ip++; --n >= 0;)
- *--q = *p++;
- sp = p;
- *--q = (Cell) lp;
- *--q = (Cell) rp;
- lp = q;
- rp = (Xt **) q;
- }
-
- code (locals_exit_execution) /* alternative EXIT */
- { /* cleans up local variable stack frame */
- lp = (Cell *) rp[1];
- rp = (Xt **) *rp;
- ip = *rp++;
- }
-
- code (local_execution) /* retrieve current value of local variable */
- {
- *--sp = lp[(Cell) *ip++];
- }
-
- code (to_local_execution) /* set current value of local variable */
- {
- lp[(Cell) *ip++] = *sp++;
- }
-
- /* 2. Actions at compile time */
-
- int
- find_local (char *nm, int l) /* returns index i to access local variable */
- { /* relative to lp [i], 0 if not defined */
- char name[32];
- int i;
-
- store_c_string (nm, l, name, sizeof name);
- if (LOWER_CASE)
- upper (name, l);
- for (i = 0; i < *sys.locals; i++)
- if (strcmp (name, sys.local[i]) == 0)
- return *sys.locals - i + 1;
- return 0;
- }
-
- int
- compile_local (char *name, int len)
- {
- static pCode cfa = local_execution_;
- int n;
-
- if ((n = find_local (name, len)) == 0)
- return 0;
- COMMA (&cfa);
- COMMA (n);
- return 1;
- }
-
- static void
- paren_local (char *nm, int l)
- {
- question_comp_ ();
- if (l == 0)
- return;
- if (l > 31)
- tHrow (THROW_NAME_TOO_LONG);
- if (LOWER_CASE)
- upper (nm, l);
- if (sys.locals == NULL)
- {
- store_c_string (nm, l, sys.local[0], 32);
- compile1 ();
- sys.locals = (Cell *) DP;
- COMMA (1);
- }
- else
- {
- if (find_local (nm, l))
- tHrow (THROW_INVALID_NAME);
- store_c_string (nm, l, sys.local[(*sys.locals)++], 32);
- }
- }
-
- Code (paren_local)
- {
- paren_local ((char *) sp[1], sp[0]);
- sp += 2;
- }
- COMPILES (paren_local, locals_bar_execution,
- SKIPS_CELL, LOCALS_STYLE);
-
- Code (locals_bar)
- {
- for (;;)
- {
- char *p = word (' ');
- int l = *(Byte *) p++;
-
- if (l == 1 && *p == '|')
- break;
- paren_local (p, l);
- }
- paren_local (NULL, 0);
- }
- COMPILES (locals_bar, locals_bar_execution,
- SKIPS_CELL, LOCALS_STYLE);
-
- LISTWORDS (locals) =
- {
- CS ("(LOCAL)", paren_local),
- CS ("LOCALS|", locals_bar)
- };
- COUNTWORDS (locals, "Locals + extensions");
-